<?php
/**
 * Author: yixuan
 * Desc:
 * Time: 2024/3/22 20:27
 */

function wxapp_decrypt($txt, $key = '')
{
    $md5 = substr($txt, 0, 6) . substr($txt, -26);
    $txt = substr($txt, 6, strlen($txt) - 32);
    if ($md5 != md5($txt)) {
        return;
    }

    $txt = wxapp_encrypt(base64_decode(urldecode($txt)), 'D', $key);

    if (substr($txt, 0, 10) != 0 && substr($txt, 0, 10) - time() < 0) {
        return;
    }
    $txt = wxapp_passport_key(substr($txt, 10), $key);
    $tmp = '';
    for ($i = 0; $i < strlen($txt); $i++) {
        $md5 = $txt[$i];
        $tmp .= $txt[++$i] ^ $md5;
    }
    $tmp = urldecode($tmp);
    return $tmp;
}

function wxapp_passport_key($txt, $encrypt_key)
{
    $encrypt_key = md5($encrypt_key);
    $ctr = 0;
    $tmp = '';

    for ($i = 0; $i < strlen($txt); $i++) {
        $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
        $tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
    }
    return $tmp;
}

//函数encrypt($string,$operation,$key)中$string：需要加密解密的字符串；$operation：判断是加密还是解密，E表示加密，D表示解密；$key：密匙。
function wxapp_encrypt($string, $operation, $key = 'yixuan')
{
    $key = md5($key);
    $key_length = strlen($key);
    $string = $operation == 'D' ? utf8_decode(base64_decode($string)) : substr(md5($string . $key), 0, 8) . $string;
    $string_length = strlen($string);
    $rndkey = $box = array();
    $result = '';
    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($key[$i % $key_length]);
        $box[$i] = $i;
    }

    for ($j = $i = 0; $i < 256; $i++) {
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }
    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a = ($a + 1) % 256;
        $j = ($j + $box[$a]) % 256;
        $tmp = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));

    }
    if ($operation == 'D') {
        if (substr($result, 0, 8) == substr(md5(substr($result, 8) . $key), 0, 8)) {
            return substr($result, 8);
        } else {
            return '';
        }
    } else {
        return str_replace('=', '', base64_encode(utf8_encode($result)));
    }
}